\input{guard.tex}   % Import common styles.
\fancyfoot[C]{Page \thepage}
\title{\productname\ Release \productversion\\
User Documentation\\
\vspace{5 mm}
\large Generic Access Lists for Python}
\author{Samuel Abels}

\begin{document}
\maketitle
\tableofcontents

\newpage
\section{Introduction}
\subsection{Why \productname?}

\product is a library for implementing user and group concepts in Python
applications. It provides access lists for defining permissions and manages 
users and available resources.
\product was developed with the following objectives in mind:

\begin{itemize}
\item {\bf Users and groups are defined hierarchically}, and permissions of 
each user or group are inherited. This is similar to the inheritance 
model known from classical software design.

\item {\bf The API is consistent} and simple enough to be used 
{\bf intuitively}.

\item {\bf Types of permissions may be freely defined.} This means that 
there is no fixed set of pre-defined permissions (e.g. ``read'', ``write'', 
...).

\item {\bf Many operations guarantee a response in near constant time}: 
Creating new users and groups, modifying permissions, requesting 
permissions of a user or group.

\item {\bf Database independence} is achieved by using the database 
abstraction library ``SQL Alchemy''. 
\end{itemize}

In the following chapter we will provide an overview over the common 
use patterns in \product.

\subsection{Legal Information}

\product and this handbook are distributed under the terms and conditions 
of the GNU GPL (General Public License) Version 2. You should have received 
a copy of the GPL along with \product. If you did not, you may read it here:

\vspace{1em}
\url{http://www.gnu.org/licenses/gpl-2.0.txt}
\vspace{1em}

If this license does not meet your requirements you may contact us under 
the points of contact listed in the following section. Please let us know 
why you need a different license - perhaps we may work out a solution 
that works for either of us.


\subsection{Contact Information \& Feedback}

If you spot any errors, or have ideas for improving \product or this 
documentation, your suggestions are gladly accepted.
We offer the following contact options: \\

\input{contact.tex}

\newpage
\section{Quick Overview}
\subsection{Initialisation}

Before using \product to manage users and groups it needs to be initialized. 
The following example shows how this is done:

\begin{lstlisting}
from sqlalchemy import create_engine
from SpiffGuard import DB
db    = create_engine('mysql://user:pass@localhost/guard_name')
guard = DB(db)
guard.install()
\end{lstlisting}

This code connects to the database using SqlAlchemy, and creates 
an instance of \product by passing the database connection as an argument. 
Calling the install() method causes the required database tables to be 
created in the connected database, if those tables do not yet exist.


\subsection{\label{intro:resources}Creating Resources}

In \product, any user, group, or object that is to be accessed, is 
represented by a {\it Resource} object. A client will first define 
the {\it types} of resources for which permissions are managed.
For example, if a programmer desires to control the access permissions 
of passengers to the rooms of a space ship, he will first define a type 
{\it Passenger} and {\it Room}, and inform \product of the 
existence of these types. The following example shows how this is done:

\begin{lstlisting}
class Passenger(Resource):
    pass

class Room(Resource):
    pass

guard.register_type([Passenger, Room])
\end{lstlisting}

We may now define specific resources using these types. In our example 
we will create the passengers ``Han Solo'' and ``Luke Skywalker''. We 
also create the rooms ``Bridge'' and ``Machine Room''.

\begin{lstlisting}
han    = Passenger("Han Solo")
luke   = Passenger("Luke Skywalker")
bridge = Room("Bridge")
mr     = Room("Machine Room")
guard.add_resource([han, luke, bridge, mr])
\end{lstlisting}

Representations of these objects are then stored in the database persistently 
and may be restored at a later time.


\subsection{\label{intro:permissions}Defining Permissions}

Of course, \product does not only let you define users and groups, it also 
lets you assign permissions to them.

Before this can be done, \product needs to know what kind of permissions 
a resource may aquire. For example, in a space ship a programmer may 
want to control permissions for {\it boarding the ship} and {\it using 
the cantina}. Another programmer may want to control access permissions 
for a web page, such as {\it viewing} and {\it modifying}.

This is achieved by defining {\it Action} objects, as can be seen in the 
following example:

\begin{lstlisting}
enter  = Action("Enter")
repair = Action("Repair")
guard.add_action([enter, repair])
\end{lstlisting}

We defined actions for entering something (for example, a room) and 
repairing something.
Now all requirements for assigning permissions with \product are met. We 
now grant Han Solo the permission to enter the machine room and repair 
things in it, while Luke Skywalker is granted the permission to enter
the machine room and the bridge:

\begin{lstlisting}
guard.grant(han, [enter, repair], mr)
guard.grant(luke, enter, [mr, bridge])
\end{lstlisting}

To later check whether Han Solo may enter the machine room the following 
request may be used:

\begin{lstlisting}
if guard.has_permission(han, enter, mr):
    print "Permission was granted."
else:
    print "Permission was denied."
\end{lstlisting}


\subsection{\label{intro:groups}Grouping Users}

We continue the above example. It would be useful if there were a way to 
group permission, such that any members of the crew may access the bridge 
without having to define this for every single member explicitely.
Similarly, we would like to grant all passengers the permission to access 
the lounge.

In \product this is done by using {\it ResourceGroup} objects. This type 
is a specialized form of a {\it Resource}, and the only difference being 
the fact that it may have children.

Resource groups may be organized hierachically, such that the following 
tree may be created:

\mygraph{intro_groups1}{Ellipses represent resource groups, rectangles 
represent simple resources.}

To build this tree we first define the resource types, and inform 
\product of their existence:

\begin{lstlisting}
class PassengerGroup(ResourceGroup):
    pass
guard.register_type(PassengerGroup)
\end{lstlisting}

We then assemble the tree in the next step:

\begin{lstlisting}
# Create the groups.
passengers = PassengerGroup("Passenger Group")
crew       = PassengerGroup("Crew Members")
engineers  = PassengerGroup("Engineers")
guests     = PassengerGroup("Guests")
guard.add_resource(None, passengers)
guard.add_resource(passengers, crew)
guard.add_resource(crew, engineers)
guard.add_resource(passengers, guests)

# Define passengers.
han  = Passenger("Han Solo")
r2d2 = Passenger("R2D2")
luke = Passenger("Luke Skywalker")
guard.add_resource(engineers, han)
guard.add_resource(engineers, r2d2)
guard.add_resource(crew, luke)

# Define rooms.
lounge = Room("Lounge")
bridge = Room("Bridge")
mr     = Room("Machine Room")
guard.add_resource(engineers, han)
guard.add_resource(crew, luke)
\end{lstlisting}

Now lets assign some permissions:

\begin{lstlisting}
guard.grant(crew,      enter,  bridge)
guard.grant(engineers, enter,  mr)
guard.grant(engineers, repair, mr)
guard.grant(guests,    enter,  lounge)
guard.deny (han,       repair, mr)
\end{lstlisting}

To define the permissions for all resources under the group ``Crew'' it is 
enough to assign them only to the group. The permissions are then inherited 
by any object below that group, so they also apply for Han Solo and R2D2.

The following tree shows the assigned permissions.

\begin{indentverb}
[Passengers]
  |- [Crew Members] -- enter -----------> Bridge
  |   |- [Engineers] -- enter, repair --> Machine Room
  |   |   |- Han Solo -- !repair -------> Machine Room
  |   |   `- R2D2
  |   `- Luke Skywalker
  `- [Guests] -- enter -----------------> Lounge
\end{indentverb}

Due to inheritance these assignments result in the following effective 
permissions:

\begin{itemize}
\item Passengers have no permission.
\item Crew members may enter the bridge.
\item Engineers may enter the bridge. They may also enter or repair the 
machine room.
\item Han Solo may enter the bridge and the machine room. He may not repair 
the machine room.
\item R2D2 may enter the bridge. He may also enter and repair the machine 
room.
\item Luke Skywalker may enter the bridge.
\item Guest may enter the lounge.
\item By default, any other permissions are denied.
\end{itemize}


\subsection{Grouping Other Resources}

Similar to the grouping of users, we may also user resource groups to 
organize other resources.
In our example, suppose a programmer needs to make the access permissions 
more fine-grained by controlling access to specific devices on the bridge.
Using the already shown methods this could only be implemented in the 
following way:

\begin{lstlisting}
class Device(Resource):
    pass
guard.register_type(Device)

use_device = Action("Use Device")
guard.add_action(use_device)

thruster = Device("Thruster")
guard.grant(crew, use_device, thruster)

laser = Device("Laser")
guard.grant(crew, use_device, thruster)

ac = Device("Air Conditioner")
guard.grant(crew, use_device, thruster)

...
\end{lstlisting}

This can be a lot of effort if the number of devices is very large.
\product offers the possibility to instead define these permissions only 
once, by categorizing the devices into different groups. For example, 
the following permissions may be specified:

\begin{indentverb}
[Devices] <-- use ------- Han Solo
  |- [Weaponry] <-- !use --'
  |   |- Laser
  |   `- Rockets
  |- Thruster
  `- Air Conditioner
\end{indentverb}

This allows Han Solo to use any devices, except for the weapons, without 
specifying this for every single device.

Of course, we may also combine the previously shown concepts, such that we 
use both, the device groups and the user groups shown in the previous chapter.
This is shown in the following tree:

\begin{indentverb}
[Passengers]
  |- [Crew Members]
  |   |- [Engineers]-------,
  |   |   |- Han Solo -----|--,
  |   |   `- R2D2          |  |
  |   `- Luke Skywalker    |  |
  `- [Guests]              |  |
                           |  |
[Devices]  <------- use ---'  |
  |- [Weaponry] <-- !use -----'
  |   |- Laser
  |   `- Rockets
  |- Thruster
  `- Air Conditioner
\end{indentverb}

Due to inheritance the following effective permissions are assigned:

\begin{itemize}
\item Passengers have no permission.
\item Crew members have no permission.
\item Engineers may use any device.
\item Han Solo may use any device, except weapons.
\item R2D2 may use any device.
\item Luke Skywalker may not use any device.
\item Guests have no permission.
\end{itemize}

\product even supports self-referencing permissions. For example, it can 
be useful to be able to grant Luke Skywalker the permission to command 
other crew members, such that the following permission is assigned:

\begin{indentverb}
[Passengers]
  |- [Crew Members] <-- command --,
  |   |- [Engineers]              |
  |   |   |- Han Solo             |
  |   |   `- R2D2                 |
  |   `- Luke Skywalker ----------'
  `- [Guests]
\end{indentverb}

This results in the following permissions:

\begin{itemize}
\item Passengers have no permission.
\item Crew members have no permission.
\item Engineers have no permission.
\item Han Solo has no permission.
\item R2D2 has no permission.
\item Luke Skywalker may command crew members, engineers, Han Solo and R2D2.
\item Guests have no permission.
\end{itemize}


\newpage
\section{Details}

\subsection{Using Resources}
\subsubsection{\label{details:resources:add}Creating a Resource}

In \product, users, groups, and any other objects for which permissions 
are defined, are represented by {\it Resource} objects.
To create a such a resource it is enough to define a class that inherits 
from {\it Resource}. We define a resource type ``Website'' as an example:

\begin{lstlisting}
class Website(Resource):
    pass
guard.register_type(Website)
\end{lstlisting}

The class {\it Website} defines a resource type.
The method {\it register\_type()} informs \product that it is responsible 
for managing resources of that type. Any class that is used with \product 
needs to be registered in this way. This will let \product provide you with 
additional ways for finding resources, as we will show in section 
\ref{details:resources:find}.

To save an instance of that class in the database it is now passed to the 
{\it add\_resource()} method:

\begin{lstlisting}
homepage = Website("Homepage")
guard.add_resource(None, homepage)
\end{lstlisting}

The code saves a representation of the object in the database and may be 
retrieved at a later time. The first argument of the method ({\it None}) 
here specifies that the saved website has no parent.

When a resource is saved, \product automatically assigns it a unique ID 
that may later be used to find it. This ID is of type {\it Integer} and 
may be accessed using the {\it get\_id()} method of the resource. An example 
for using the ID to find a resource can be found in section 
\ref{details:resources:find}.

We will now define additional websites and place them as children under the 
homepage. In our definition of the website we previously inherited from 
{\it Resource}. However, this will not work, because objects of this type 
can not have children. As a result, the following call will fail with an 
exception:

\begin{lstlisting}
page = Website("Another Page")
guard.add_resource(homepage, page)
\end{lstlisting}

This is solved by using the {\it ResourceGroup} type.

\hint{Objects that may have children must inherit from {\it ResourceGroup}.}

Using the ResourceGroup object, the following code completes the example:

\begin{lstlisting}
class Website(ResourceGroup):
    pass
guard.register_type(Website)

homepage = Website("Homepage")
page     = Website("Another Page")
guard.add_resource(None, homepage)
guard.add_resource(homepage, page)
\end{lstlisting}

It is also possible to assign a {\it handle} to a resource, which is a string 
that may be used to look the resource up at any time. There are two ways to 
define such a handle:

\begin{enumerate}
\item Using the optional second argument of the resource constructor:

\begin{lstlisting}
class Website(ResourceGroup):
    pass
homepage = Website("Homepage", "home")
\end{lstlisting}

\item Using the {\it set\_handle()} method of the Resource:

\begin{lstlisting}
homepage = Website("Homepage")
homepage.set_handle("home")
\end{lstlisting}
\end{enumerate}

Instructions on how to find resources using the handle are shown in section 
\ref{details:resources:find}.


\subsubsection{\label{details:resources:attributes}Assigning Attributes}

We have shown how resources are defined and stored in \product. We will now 
connect additional information to a resource, and store both together in the 
database. To do this, \product supports {\it attributes}, which are used as 
shown in the following example:

\begin{lstlisting}
class User(Resource):
    pass
guard.register_type(User)

user = Website("Administrator", "admin")
user.set_attribute("email", "invalid@debain.org")
guard.add_resource(None, user)
\end{lstlisting}

When retrieving an object later the attributes are still available:

\begin{lstlisting}
user = guard.get_resource(handle = "admin")
print "Email address:", user.get_attribute("email")
\end{lstlisting}

In practice, the {\it set\_attribute()} and {\it get\_attribute()} methods 
may be used in the following way:

\begin{lstlisting}
class Website(ResourceGroup):
    def __init__(self, *args):
        ResourceGroup.__init__(self, *args)
        self.set_attribute("content", "<h1>Empty Page</h1>")

    def get_content(self):
        return self.get_attribute("content")
\end{lstlisting}


\subsubsection{\label{details:resources:find}Finding Resources}

\product provides two methods to retrieve existing resources. The first 
method, {\it get\_resources()}, selects a {\it list} of results using 
the given criterias. The second method, {\it get\_resource()} may be used 
if it is known in advance that a search will not produce more than one 
single result. One example where this is commonly used is when using a 
unique key such as the resource ID to look up a resource. \product raises 
an exception if a search with {\it get\_resource()} produces more than one 
match.

The following list of possible criterias is identical for both methods:

\begin{enumerate}
\item {\bf ID}: \product assigns an ID to every resource stored in the 
database. This integer value is unique and may be used at any time to 
retrieve the object from the database.

\begin{lstlisting}
homepage = Website("Homepage")
guard.add_resource(homepage)
homepage_id = homepage.get_id()

page = guard.get_resource(id = homepage_id)
print "Page name:", page.get_name()
\end{lstlisting}

\item {\bf Handle}: Similar to the ID, a {\it handle} provides a way to 
retrieve one, specific resource. However, unlike the ID, a handle may be 
freely assigned to a resource (as shown in section 
\ref{details:resources:add}). We provide another example:

\begin{lstlisting}
homepage = Website("Homepage", "my_handle")
guard.add_resource(homepage)

page = guard.get_resource(handle = "my_handle")
print "Page name:", page.get_name()
\end{lstlisting}

\item {\bf Resource name}: Every resource has a name that is passed to 
the constructor as mandatory argument. Unlike the previously shown
{\it handle}, a name is not necessarily unique, so a search may also 
produce multiple results. The following example retrieves one single 
resource using its name:

\begin{lstlisting}
homepage = Website("Homepage", "my_handle")
guard.add_resource(homepage)

page = guard.get_resource(name = "Homepage")
print "Page name:", page.get_name()
\end{lstlisting}

\item {\bf Attribute}: Resources that have attributes assigned (see also 
section \ref{details:resources:attributes}) may also be found using these 
attributes as a search criteria:

\begin{lstlisting}
result = guard.get_resources(attribute = {'my_attribute': 'my_value',
                                          'attribute2':   'my_other_value'})
\end{lstlisting}

If multiple attributes are specified (as shown in the example) the search 
is made using a logical AND.

\item {\bf Python class (Python type)}: 

If a resource tree (see also section \ref{intro:resources}) contains objects 
of different Python types it can sometimes be useful to retrieve only objects 
that have a specific type. For example, given the following resource tree; 
terms in brackets specify the Python type: 

\begin{indentverb}
Passenger (UserGroup)
  |- Crew (UserGroup)
  |   |- Han Solo (Person)
  |   `- R2D2 (Robot)
  `- Luke Skywalker (Person)
\end{indentverb}

The resource types ({\it UserGroup}, {\it Person}, {\it Robot}) are defined 
as follows:

\begin{lstlisting}
class UserGroup(ResourceGroup):
    pass
class User(Resource):
    pass
class Person(User):
    pass
class Robot(User):
    pass
guard.register_type([UserGroup, Person, Robot])
\end{lstlisting}

We use the following request to find a list of all resources that have the 
Python type ``Person'' from the tree.

\begin{lstlisting}
result = guard.get_resources(type = Person)
for person in result:
    print "Person:", person.get_name()
\end{lstlisting}

The search produces ``Han Solo'' and ``Luke Skywalker'' as a result.

Another possibility to retrieve resources using the Python type functions 
by using the {\bf type introspection} feature of Python. Because \product 
is aware of the base classes of any object used with it, we may also find 
any objects that {\it derive} from the ``User'' class:

\begin{lstlisting}
result = guard.get_resources(type = User)
for user in result:
    print "User:", user.get_name()
\end{lstlisting}

The result then also contains a list of all sub-types of the User class, 
in this case ``Han Solo'', ``R2D2'', and ``Luke Skywalker''.
\end{enumerate}


\subsubsection{\label{details:resources:modify}Modifying a Resource}

Modifying an existing resource functions functions in a way that is 
similar to creating resources. Example:

\begin{lstlisting}
class Website(ResourceGroup):
    pass

guard.register_type(Website)
homepage = Website("Homepage", "home")
guard.add_resource(None, homepage)

# The resource is now saved. Let's make a change.
homepage.set_name("Welcome!")
homepage.set_handle("my_new_handle")
guard.save_resource(homepage)
\end{lstlisting}

In other words, the only difference is in using the {\it save\_resource()} 
method in place of the {\it add\_resource()} method.


\subsubsection{\label{details:resources:delete}Deleting a Resource}

The simplest way to delete a resource is by passing it to the 
{\it delete\_resource()} method:

\begin{lstlisting}
class Website(ResourceGroup):
    pass

guard.register_type(Website)
homepage = Website("Homepage", "home")
guard.add_resource(None, homepage)

# The resource is now saved. Let's delete it.
guard.delete_resource(homepage)
\end{lstlisting}

However, the object instance may not always be available in practice. For 
such situations, \product provides a method that is similar to the methods 
for finding objects. It lets you delete all resources that match specific 
criteria. Any of the criteria specicified in section 
\ref{details:resources:find} may be used. We provide another example:

\begin{lstlisting}
deleted = guard.delete_resource_from_match(handle = "home")
print "%s resources deleted!" % deleted
\end{lstlisting}


\subsection{Actions}
\subsubsection{Why Use Actions?}

Before a resource may be granted or denied a specific permission, \product 
needs to be informed of the types of actions that are available for granting 
and denying. The following sections explain how such actions are defined 
and managed.

\subsubsection{Creating an Action}

In order to define an action, an instance is created and passed to \product. 
We demonstrate this with the following example:

\begin{lstlisting}
read  = Action("Read")
write = Action("Write", "write")
guard.add_action([read, write])
\end{lstlisting}

The example also shows that the constructor of the ``Write'' action is 
passed an additional argument. This argument is a {\it handle} that may be 
used to find the action later. This functionality is equivalent to the 
handle of resource objects, as seen in section \ref{details:resources:add}.


\subsubsection{\label{details:actions:find}Finding Actions}

If we are only looking for one single action, the {\it get\_action()} method 
is used. This method fails if more than one result is produced. For finding 
multiple results, the {\it get\_actions()} method may be used.

The list of the following possible criteria is identical in both methods:

\begin{enumerate}
\item {\bf ID}: \product automatically assigns an ID to every saved action. 
This integer value is unique and may be used at any time to retrieve the 
resource from the database.

\begin{lstlisting}
guard.add_action(Action("Read a File", "read"))
action_id = read.get_id()

# Find the action.
action = guard.get_action(id = action_id)
print "Action name:", action.get_name()
\end{lstlisting}

\item {\bf Handle}: Similar to the ID, a {\it handle} provides a way to 
retrieve one, specific action. However, unlike the ID, a handle may be 
freely assigned to a action (as shown above). We provide another example:

\begin{lstlisting}
guard.add_action(Action("Read a File", "read"))

action = guard.get_action(handle = "read")
print "Action name:", action.get_name()
\end{lstlisting}

\item {\bf Action name}: Every action has a name that is passed to 
the constructor as mandatory argument. Unlike the previously shown
{\it handle}, a name is not necessarily unique, so a search may also 
produce multiple results. The following example retrieves one single 
action using its name:

\begin{lstlisting}
action = guard.get_action(name = "Read a File")
\end{lstlisting}

\item {\bf Python class (Python type)}: 

When an action was defined by passing an {\it Action} derived class to 
\product, these Python types may also be used to look up an object.

Given the action derived types {\it UserAction} and {\it WebsiteAction} as 
specified in the following code:

\begin{lstlisting}
class MyAction(Action):
    pass
class UserAction(MyAction):
    pass
class WebsiteAction(MyAction):
    pass
guard.register_type([UserAction, WebsiteAction])
guard.add_action(UserAction("Edit User"))
guard.add_action(WebsiteAction("Edit Website"))
\end{lstlisting}

We may use the following request to retrieve all object as type 
``UserAction'':

\begin{lstlisting}
for action in guard.get_actions(type = UserAction):
    print "Action:", action.get_name()
\end{lstlisting}

The search produces the single action ``Edit User'' as a result.

Due to {\bf type introspection}, any subtypes may be retrieved as 
well, because \product is aware of the base types of any object.
Example:

\begin{lstlisting}
for action in guard.get_actions(type = MyAction):
    print "Action:", action.get_name()
\end{lstlisting}

The request then also contains subtypes of MyAction, in this case the actions 
``Edit User'' and ``Edit Website''.
\end{enumerate}


\subsubsection{Modifying an Action}

Modifying an action is similar to creating a new one; the difference being 
that a resource is passed to the {\it save\_resource()} method instead:

\begin{lstlisting}
read = Action("Read")
guard.add_action(read)

# Change an action.
read.set_handle("read")
guard.save_action(read)
\end{lstlisting}


\subsubsection{Deleting an Action}

If the object instance is available, the {\it delete\_action()} method may 
be used as follows:

\begin{lstlisting}
read  = Action("Read")
write = Action("Write")
guard.add_action([read, write])

# Delete an action.
guard.delete_action(read)
\end{lstlisting}

Another possibility is the use of searh criterias with the 
{\it delete\_action\_from\_match()} method:

\begin{lstlisting}
guard.delete_action_from_match(id = 1234)
\end{lstlisting}

The list of accepted search criteria is identical to the criteria of the 
{\it get\_actions()} method.


\subsection{ACLs}
\subsubsection{What Is an ACL?}

An ACL specifies whether or not a specific resource has the permission to 
access another specific resource. Permissions of individual users and groups 
are determined by looking at an ACL. The exact way in which an ACL is 
implemented is hidden from the programmer in \product. He only needs to 
inform \product of the permissions that he desires to assign to a resource.


\subsubsection{Formal Description of ACLs}

An access list may be understood as a tuple (A, R, C, p), such that:

\begin{itemize}
\item A is an actor, such as a human user or a user group.
\item R is an object that is accessed, e.g. an internet site or rooms on a 
ship.
\item C is an action, e.g. ``read'', ``write'', ``jump'', ...
\item p is either true or false.
\end{itemize}

\hint{To provide additional ease of use, in \product actors and accessed 
objects are both represented by classes of the same type, {\it Resource}.}

\product is responsible for creating, managing, and searching lists of ACLs. 
Methods provided by \product my thus be formally understood as functions on 
a space of ACLs. The following sections document these functions.


\subsubsection{Assigning a Permission}

Given the following resource tree:

\begin{indentverb}
Everybody
  |- Administrators
  |   `- Luke Skywalker
  `- Users
      |- Han Solo
      `- R2D2
Homepage
  |- Subpage 1
  |   |- Subpage 1.1
  |   `- Subpage 1.2
  `- Subpage 2
\end{indentverb}

We will now assign permissions such that the following criteria are met:

\begin{itemize}
\item Administrators may alter the name of any other user.
\item Administrators may view and edit any website.
\item Normal users ({\it Users} class) may view any Website, except for 
Subpage 1 and any of its children.
\item Any other users may only see the homepage.
\end{itemize}

The following code only shows the assignment of permissions. For instructions 
on how to define and manage resources please refer to section 
\ref{details:resources:add}.

\begin{lstlisting}
class UserAction(Action):
    pass
class WebsiteAction(Action):
    pass
guard.register_type([UserAction, WebsiteAction])

# Create actions.
edit_user    = UserAction("Edit User")
view_website = WebsiteAction("View Website")
edit_website = WebsiteAction("Edit Website")
guard.add_action([edit_user, view_website, edit_website])

# Assign permissions.
guard.grant(administrators, edit_user, everybody)
guard.grant(administrators, view_website, homepage)
guard.grant(administrators, edit_website, homepage)
guard.grant(users, view_website, homepage)
guard.deny(users, view_website, subpage1)
guard.grant(everybody, view_website, homepage)
guard.deny(everybody, view_website, subpage1)
guard.deny(everybody, view_website, subpage2)
\end{lstlisting}

Any call of the {\it grant()} or {\it deny()} methods represents the creation 
of a new ACL. The exact same assignment may also be done in the following way:

\begin{lstlisting}
guard.grant(administrators, edit_user, everybody)
guard.grant(administrators, [view_website, edit_website], homepage)
guard.grant(users, view_website, [homepage, subpage1])
guard.grant(everybody, view_website, homepage)
guard.deny(everybody, view_website, [subpage1, subpage2])
\end{lstlisting}

The above specified requirements are now defined and saved. It should be 
mentioned that the order in which permissions are specified is irrelevant. 
In other words, inheritance is resolved at runtime, not at the time at which 
a permission is defined.


\subsubsection{Modifying a Permission}

When changing existing permissions, the following two cases need to 
be considered:

\begin{enumerate}
\item A permission should be replaced, such that a granted permission is 
changed into a denial, or a denial is changed into a granted permission. 
In other words, an existing ACL is replaced. Example:

\begin{lstlisting}
guard.grant(users, view_website, subpage1)

# The following command changes the ACL.
guard.deny(users, view_website, subpage1)
\end{lstlisting}

\item A permission should be revoked, i.e. a granted permission or a 
denial is removed such that default permissions are restored. In other words, 
an existing ACL is removed.

\begin{lstlisting}
guard.grant(users, view_website, subpage1)

# The following command deletes the ACL.
guard.delete_permission(users, view_website, subpage1)
\end{lstlisting}
\end{enumerate}


\subsubsection{Checking a Permission}

Once permissions are defined and saved using the mechanisms shown above, 
they may now be checked using the following, simple request:

\begin{lstlisting}
if guard.has_permission(users, view_website, subpage1):
    print "Yes"
else:
    print "No"
\end{lstlisting}

In practice, the object instance is not always available, and it would be 
handy if it were not necessary to retrieve it from the database only to 
destroy it. This can be done using the 
{\it has\_permission\_from\_id()} method, which accepts the ID of the objects 
instead.

\begin{lstlisting}
if guard.has_permission_from_id(user.get_id(), view_website_id, subpage1_id):
    print "Yes"
else:
    print "No"
\end{lstlisting}


\subsubsection{Finding ACLs}

We have shown in the previous section how a single permission is defined 
and checked using inheritance. In some cases we want to be able to query 
more detailed information regarding which ACLs are actually causing a 
specific effective permission. In other words, we may want to retrieve 
an exact list of currently defined ACLs.

In such cases the {\it get\_permission\_list\_from\_id()} method may be 
used. It provides a list of ACLs that match a number of given criteria.

\hint{The result of this method does {\it not} contain resources that 
only inherited a permission. Instead, inheritance is completely ignored.}

For cases in which inheritance is to be honored, \product provides the 
{\it get\_permission\_list\_from\_id\_with\_inheritance()} method.

In the below examples we expect that the following resource tree is 
already defined:

\begin{indentverb}
Everybody
  |- Administrators
  |   `- Luke Skywalker
  `- Users
      |- Han Solo
      `- R2D2
Homepage
  |- Subpage 1
  |   |- Subpage 1.1
  |   `- Subpage 1.2
  `- Subpage 2
\end{indentverb}

The following criteria are supported by both methods:

\begin{enumerate}
\item {\bf Action ID}: This ID is passed using the {\it action\_id} argument. 
The example queries any permissions that are defined for a given user:

\begin{lstlisting}
guard.grant(administrator, view, homepage)
guard.grant(administrator, view, subpage1_1)
guard.deny(administrator, view, subpage2)

result = guard.get_permission_list_from_id(administrator.get_id(),
                                           action_id = view.get_id())
\end{lstlisting}

The result contains three ACLs, which may be represented by the following 
tuples:

\begin{lstlisting}
(administrator, view, homepage,   True)
(administrator, view, subpage1_1, True)
(administrator, view, subpage2,   False)
\end{lstlisting}

\item {\bf Resource ID}: In order to determine all permissions of one 
specific user on one specific object, the following code may be used:

\begin{lstlisting}
guard.grant(administrator, remove, homepage)
guard.grant(administrator, view,   subpage1)
guard.grant(administrator, edit,   subpage1)

result = guard.get_permission_list_from_id(administrator.get_id(),
                                           resource_id = subpage1.get_id())
\end{lstlisting}

The query generates the following results:

\begin{lstlisting}
(administrator, view, subpage1, True)
(administrator, edit, subpage1, True)
\end{lstlisting}

\item {\bf Action type}: Similar to the search for actions, it is possible 
to restrict the result to any ACLs that were defined using actions of one 
specific type. This is done using the {\it action\_type} argument. For more 
details regarding action types please refer to section 
\ref{details:actions:find}.

\item {\bf Resource type}: Like the action type criteria, the resource type 
may also be used to filter the results, such that only ACLs for a user of 
the specified type are returned. For more information regarding resource 
types please refer to section \ref{details:resources:find}.
\end{enumerate}

In all examples the resulting ACLs may be printed using the following code:

\begin{lstlisting}
for acl in result:
    uid    = acl.get_actor_id()
    action = acl.get_action().get_name()
    rid    = acl.get_resource_id()
    if acl.get_permit():
        msg = "User with ID %s may %s the resource with ID %s."
        print msg % (uid, action, rid)
    else:
        msg = "User with ID %s may not %s the resource with ID %s."
        print msg % (uid, action, rid)
\end{lstlisting}


\newpage
\section{Examples}
\subsection{Simple}

\lstinputlisting{examples/simple.py}


\subsection{Permissions With User Groups}

\lstinputlisting{examples/permissions-with-groups.py}


\subsection{Permissions With User Groups And Recursion}

\lstinputlisting{examples/permissions-with-user-groups-and-recursion.py}
\end{document}
